<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>公共聊天室</title>
    <script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
    <style>
        body { font-family: sans-serif; margin: 0; display: flex; height: 100vh; background-color: #f0f2f5; }
        #app-container { width: 100%; max-width: 800px; margin: 0 auto; display: flex; flex-direction: column; height: 100%; box-shadow: 0 0 15px rgba(0,0,0,0.1); }
        #messages { flex-grow: 1; overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 12px; background-color: #ffffff; }
        .message { padding: 8px 12px; border-radius: 18px; max-width: 70%; line-height: 1.4; word-wrap: break-word; }
        .message.mine { background-color: #dcf8c6; align-self: flex-end; }
        .message.other { background-color: #f1f1f1; align-self: flex-start; }
        .message .sender { font-weight: bold; font-size: 0.8em; color: #555; margin-bottom: 4px; }
        .message .timestamp { font-size: 0.7em; color: #999; margin-left: 8px; }
        .message .content a { color: #007bff; }
        #form { display: flex; padding: 15px; border-top: 1px solid #ddd; background-color: #f8f9fa; }
        #input { flex-grow: 1; padding: 10px; border: 1px solid #ccc; border-radius: 20px; resize: none; }
        #send, #upload-button { background-color: #007bff; color: white; border: none; padding: 0 20px; height: 40px; border-radius: 20px; margin-left: 10px; cursor: pointer; }
        #upload-button { background-color: #28a745; }
        #upload-input { display: none; }
        #context-menu { display: none; position: absolute; background-color: #fff; border: 1px solid #ddd; box-shadow: 0 2px 5px rgba(0,0,0,0.1); border-radius: 5px; z-index: 1000; padding: 5px 0; }
        #context-menu div { padding: 8px 15px; cursor: pointer; }
        #context-menu div:hover { background-color: #f0f0f0; }
    </style>
</head>
<body>
    <div id="app-container">
        <ul id="messages"></ul>
        <form id="form" action="">
            <input id="input" autocomplete="off" placeholder="输入消息..."/>
            <input type="file" id="upload-input"/>
            <button type="button" id="upload-button">文件</button>
            <button id="send">发送</button>
        </form>
    </div>

    <div id="context-menu">
        <div id="context-copy">复制</div>
        <div id="context-copy-link">复制链接</div>
        <div id="context-delete">删除</div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const socket = io();
            const messages = document.getElementById('messages');
            const form = document.getElementById('form');
            const input = document.getElementById('input');
            const uploadButton = document.getElementById('upload-button');
            const uploadInput = document.getElementById('upload-input');
            const contextMenu = document.getElementById('context-menu');
            const contextCopy = document.getElementById('context-copy');
            const contextCopyLink = document.getElementById('context-copy-link');
            const contextDelete = document.getElementById('context-delete');
            
            let mySid = null;
            let targetMessage = null;

            // Store SID on connect
            socket.on('connect', () => {
                mySid = socket.id;
            });

            // --- Message Rendering ---
            function renderMessage(msg) {
                const item = document.createElement('li');
                item.dataset.id = msg.id;
                item.dataset.sid = msg.sid;
                item.dataset.type = msg.type; // Store message type
                
                const senderSpan = document.createElement('div');
                senderSpan.className = 'sender';
                senderSpan.textContent = msg.sid === mySid ? '我' : `匿名用户 ${msg.sid.substring(0, 4)}`;
                
                const contentDiv = document.createElement('div');
                contentDiv.className = 'content';

                if (msg.type === 'text') {
                    contentDiv.textContent = msg.content;
                } else if (msg.type === 'file') {
                    const link = document.createElement('a');
                    link.href = msg.url;
                    link.textContent = `文件: ${msg.filename}`;
                    link.target = '_blank';
                    contentDiv.appendChild(link);
                }

                item.appendChild(senderSpan);
                item.appendChild(contentDiv);
                item.classList.add('message');
                item.classList.toggle('mine', msg.sid === mySid);
                item.classList.toggle('other', msg.sid !== mySid);
                
                item.addEventListener('contextmenu', (e) => {
                    e.preventDefault();
                    targetMessage = e.currentTarget;
                    const isMine = targetMessage.dataset.sid === mySid;
                    const messageType = targetMessage.dataset.type;

                    contextDelete.style.display = isMine ? 'block' : 'none';

                    if (messageType === 'file') {
                        contextCopy.style.display = 'none';
                        contextCopyLink.style.display = 'block';
                    } else {
                        contextCopy.style.display = 'block';
                        contextCopyLink.style.display = 'none';
                    }

                    contextMenu.style.top = `${e.pageY}px`;
                    contextMenu.style.left = `${e.pageX}px`;
                    contextMenu.style.display = 'block';
                });

                messages.appendChild(item);
                messages.scrollTop = messages.scrollHeight;
            }

            // --- Socket Event Listeners ---
            socket.on('init', (history) => {
                messages.innerHTML = '';
                history.forEach(renderMessage);
            });

            socket.on('message', (msg) => {
                renderMessage(msg);
            });

            socket.on('message_deleted', (data) => {
                const el = document.querySelector(`li[data-id="${data.id}"]`);
                if (el) {
                    el.remove();
                }
            });

            // --- Form and Button Event Handlers ---
            form.addEventListener('submit', (e) => {
                e.preventDefault();
                if (input.value) {
                    socket.emit('message', input.value);
                    input.value = '';
                }
            });

            uploadButton.addEventListener('click', () => {
                uploadInput.click();
            });

            function uploadFile(file) {
                if (!file) return;

                const formData = new FormData();
                formData.append('file', file);
                formData.append('sid', mySid);

                fetch('/api/upload', {
                    method: 'POST',
                    body: formData
                })
                .then(res => res.json())
                .then(data => {
                    if (!data.success) {
                        alert('文件上传失败: ' + (data.error || '未知错误'));
                    }
                })
                .catch(err => {
                    console.error('Upload error:', err);
                    alert('文件上传失败。');
                });
            }

            uploadInput.addEventListener('change', () => {
                if (uploadInput.files.length > 0) {
                    uploadFile(uploadInput.files[0]);
                    uploadInput.value = ''; // Reset input
                }
            });

            document.addEventListener('paste', (e) => {
                const items = (e.clipboardData || e.originalEvent.clipboardData).items;
                let file = null;
                for (const item of items) {
                    if (item.kind === 'file' && item.type.startsWith('image/')) {
                        file = item.getAsFile();
                        break;
                    }
                }

                if (file) {
                    e.preventDefault();
                    uploadFile(file);
                }
            });

            // --- Clipboard Helper ---
            function copyToClipboard(text, successCallback, errorCallback) {
                if (navigator.clipboard && window.isSecureContext) {
                    navigator.clipboard.writeText(text).then(successCallback).catch(errorCallback);
                } else {
                    const textArea = document.createElement('textarea');
                    textArea.value = text;
                    textArea.style.position = 'fixed';
                    textArea.style.top = '-9999px';
                    textArea.style.left = '-9999px';
                    document.body.appendChild(textArea);
                    textArea.focus();
                    textArea.select();
                    try {
                        const successful = document.execCommand('copy');
                        if (successful) {
                            successCallback();
                        } else {
                            errorCallback();
                        }
                    } catch (err) {
                        errorCallback(err);
                    }
                    document.body.removeChild(textArea);
                }
            }

            // --- Context Menu Logic ---
            document.addEventListener('click', () => {
                contextMenu.style.display = 'none';
                targetMessage = null;
            });

            contextCopy.addEventListener('click', () => {
                if (targetMessage) {
                    const content = targetMessage.querySelector('.content').textContent;
                    copyToClipboard(content, 
                        () => alert('已复制到剪贴板'),
                        (err) => {
                            console.error('Copy failed:', err);
                            alert('复制失败');
                        }
                    );
                }
            });

            contextCopyLink.addEventListener('click', () => {
                if (targetMessage) {
                    const linkElement = targetMessage.querySelector('.content a');
                    if (linkElement) {
                        const url = linkElement.href;
                        copyToClipboard(url,
                            () => alert('链接已复制到剪贴板'),
                            (err) => {
                                console.error('Copy link failed:', err);
                                alert('复制链接失败');
                            }
                        );
                    }
                }
            });

            contextDelete.addEventListener('click', () => {
                if (targetMessage) {
                    const messageId = targetMessage.dataset.id;
                    socket.emit('delete_message', messageId);
                }
            });
        });
    </script>
</body>
</html> 